/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package FilePartsTransferTest;

import com.sun.org.apache.bcel.internal.generic.NEWARRAY;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

/**
 *
 * @author Victor
 */
public class Server {
        
    private static int LISTENING_PORT = 40100;
    private static int CHUNK_SIZE = 1024 * 1024;      
    ArrayList<Boolean> completeParts;
    
    private int firstIncompletePartIndex = 0;
            
    public Server() throws IOException{
        completeParts = new ArrayList<>();

        File myFile = new File("input.png");
        
        completeParts = setFileParts(myFile);
        
        //int partIndex = getRandomIncompletePart(completeParts);
        

        ServerSocket servsock = new ServerSocket(LISTENING_PORT);
        Socket sock = servsock.accept();
        System.out.println("Socket open");
        
        
        System.out.println("sending first part");
        sendPart(0, myFile, sock);    
//        System.out.println("sending second part");
//        sendPart(1, myFile, sock);

        
        sock.close();
        
        
    }

    private void sendPart(int partIndex, File myFile,Socket sock) throws FileNotFoundException, IOException {

        byte[] byteBuffer = new byte[CHUNK_SIZE];
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
        
        bis.skip(partIndex * CHUNK_SIZE);
        bis.read(byteBuffer, 0, CHUNK_SIZE);
        
        OutputStream os = sock.getOutputStream();
        stream(bis,os);
    }
    
    
    
    public static void stream(BufferedInputStream in, OutputStream out) throws IOException {
        byte[] buf = new byte[1024];
        int bytesRead = 0;

        try {
            while (-1 != (bytesRead = in.read(buf, 0, buf.length))) {
                out.write(buf, 0, bytesRead);
            }
        } catch (IOException e) {
            throw (e);
        } finally {
            try{
               in.close();
               out.flush();
               out.close();
            } catch (Exception e){}//Ignore
        }
    }
    
    private ArrayList<Boolean> setFileParts(File myFile) {
        ArrayList<Boolean> parts = new ArrayList<>();
        int size = (int)(myFile.length() / 1024) + 1; //File size limit is 1GB
        
        for(int i = 0; i < size; i++) {
            parts.add(false);
        }
        return parts;
    }
    
    
    //Returns -1 when all parts are finished
    private int getRandomIncompletePart(ArrayList<Object> completeParts){
        
        int index = (int) (Math.random() * (completeParts.size()-1));
        
        if(completeParts.get(index) == true) {
            //Return to beggining
            index = firstIncompletePartIndex;
            firstIncompletePartIndex++;
        }
        
        while(completeParts.get(index) == true) {
            index++;
            firstIncompletePartIndex++;
            if(index == completeParts.size()) {
                //When end is reached
                return -1;
            }
        }
        return index;
    }


}
